package main

import (
	"crypto/tls"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"net/http/cookiejar"
	"time"
)

func main() {

	// 启动 HTTPS 服务器，支持动态证书选择
	server := &http.Server{
		Addr: ":443",
		TLSConfig: &tls.Config{
			GetCertificate: getCertificateForSNI,
		},
	}

	// 注册 HTTPS 请求处理函数
	http.HandleFunc("/proxy", handleHttpsRequest)


	// 启动 HTTPS 服务器
	log.Println("Starting HTTPS server on https://localhost:443")
	if err := server.ListenAndServeTLS("", ""); err != nil {
		log.Fatal("ListenAndServeTLS: ", err)
	}
}

func getCertificateForSNI(helloInfo *tls.ClientHelloInfo) (*tls.Certificate, error) {
	switch helloInfo.ServerName {
	case "server1.com":
		cert, err := tls.LoadX509KeyPair("server1.crt", "server1.key")
		return &cert, err // 返回结构体的指针
	case "server2.com":
		cert, err := tls.LoadX509KeyPair("server2.crt", "server2.key")
		return &cert, err // 返回结构体的指针
	default:
		return nil, fmt.Errorf("no certificate found for SNI: %s", helloInfo.ServerName)
	}
}


func handleHttpsRequest(w http.ResponseWriter, req *http.Request) {
	targetURL := req.Header.Get("X-Target-URL")
	if targetURL == "" {
		http.Error(w, "缺少 X-Target-URL 请求头", http.StatusBadRequest)
		return
	}

	parsedURL, err := url.Parse(targetURL)
	if err != nil {
		http.Error(w, "无效的目标URL", http.StatusBadRequest)
		return
	}

	// 构造新请求
	proxyReq, _ := http.NewRequest(req.Method, targetURL, req.Body)
	proxyReq.Header = req.Header.Clone()
	proxyReq.Header.Del("Host")
	proxyReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
	proxyReq.Header.Set("Accept-Language", "en-US,en;q=0.9")
	proxyReq.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
	proxyReq.Header.Set("Referer", "https://www.google.com/")
	proxyReq.Host = parsedURL.Host // 修正Host头

	// 安全配置TLS客户端
	jar, _ := cookiejar.New(nil) // Cookie持久化
	client := &http.Client{
		Jar: jar,
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 生产环境应使用有效证书
		},
		Timeout: 10 * time.Second,
	}

	// 转发请求
	resp, err := client.Do(proxyReq)
	if err != nil {
		http.Error(w, "转发请求失败: "+err.Error(), http.StatusBadGateway)
		return
	}
	defer resp.Body.Close()

	// 回传响应头
	for k, v := range resp.Header {
		w.Header()[k] = v
	}
	w.WriteHeader(resp.StatusCode)

	// 回传响应内容
	if _, err := io.Copy(w, resp.Body); err != nil {
		log.Printf("响应回传错误: %v", err)
	}
}